﻿// patterns.cpp: 定义应用程序的入口点。
#include "patterns.h"
#include "src/singleton/singleton.h"
#include "src/factory/simple/simple.h"
#include "src/factory/factorymethod/factory_method.h"
#include "src/factory/abstractfactory/abstract_factory.h"
#include "src/builder/builder.h"
#include "src/builder2/builder2.h"
#include "src/prototype/prototype.h"





/*单例模式*/
void singleton() {
	std::cout << "---------------singleton--------------" << std::endl;
	Singleton& s = Singleton::getInstance();

	s.test();

	std::cout << std::endl;
}

/*简单工厂*/
void simple_factory() {
	std::cout << "---------------simple_factory--------------" << std::endl;

	// 构造工厂对象
	ShoesFactory shoesFactory;

	Shoes* nikeShoes = shoesFactory.createShoes(NIKE);

	if (nikeShoes != nullptr)
	{
		// 耐克球鞋广告喊起
		nikeShoes->Show();

		// 释放资源
		delete nikeShoes;
		nikeShoes = NULL;
	}

	std::cout << std::endl;
}

/*工厂方法*/
void factory_methods() {
	std::cout << "---------------factory_methods--------------" << std::endl;
	fm::ShoesFactory* nikeFactory = new fm::NikeProducer();
	fm::Shoes* nikeShoes = nikeFactory->createShoes();

	nikeShoes->show();

	delete nikeShoes;
	delete nikeFactory;

	std::cout << std::endl;
}

/*抽象工厂*/
void abstract_factory() 
{
	std::cout << "---------------abstract_factory--------------" << std::endl;
	af::Factory* nikeFactory = new af::NikeFactory();
	
	af::Shoes* nikeShoes = nikeFactory->createShoes();
	af::Clothe* nikeCLothe = nikeFactory->createClothe();

	nikeShoes->show();
	nikeCLothe->show();

	delete nikeCLothe;
	delete nikeShoes;
	delete nikeFactory;

	std::cout << std::endl;
}

void builderPatterns()
{
	std::cout << "---------------builder--------------" << std::endl;

	builder::Builder* builderObj = new builder::FatManBuilder();
	builder::Director directorObj(builderObj);
	directorObj.CreateMan();
	builder::Man* manObj = builderObj->GetMan();
	if (manObj == NULL)
		return ;

	manObj->showMan();

	delete manObj;
	manObj = NULL;

	delete builderObj;
	builderObj = NULL;

	std::cout << std::endl;
}


void builderPatterns2() 
{
	std::cout << "---------------builder2--------------" << std::endl;

	builder2::IBuilder* xiaomi = new builder2::XiaomiBuilder;
	builder2::IBuilder* iphone = new builder2::IPhoneBuilder;

	builder2::Director* director = new builder2::Director;
	director->create(xiaomi);
	director->create(iphone);

	builder2::Phone* xiaomi_phone = xiaomi->get_phone();
	builder2::Phone* iphone_phone = iphone->get_phone();

	xiaomi_phone->display_camera();
	xiaomi_phone->display_battery();
	xiaomi_phone->display_screen();

	iphone_phone->display_camera();
	iphone_phone->display_battery();
	iphone_phone->display_screen();


	delete xiaomi ;
	delete xiaomi_phone;
	delete iphone;
	delete iphone_phone;
	delete director ;

	std::cout << std::endl;
}


void prototypePatterns()
{
	std::cout << "---------------prototype--------------" << std::endl;

	prototype::Prototype* p = new prototype::ConcretePrototype();
	prototype::Prototype* p1 = p->clone();


	std::cout << "p->xxx = " << p->xxx  << " p->xxx address = " << &(p->xxx)  << std::endl;
	std::cout << "p1->xxx = " << p1->xxx << " p1->xxx address = " << &(p1->xxx) << std::endl;

	std::cout << "p->yyy = " << *(p->yyy) << " p->yyy address = " << p->yyy << std::endl;
	std::cout << "p1->yyy = " << *(p1->yyy) << " p1->yyy address = " << p1->yyy << std::endl;


	std::cout << "p->otherCopy = " << p->otherCopy << std::endl;
	std::cout << "p1->otherCopy = " << p1->otherCopy << std::endl;



	std::cout << "p addres " << p << std::endl;
	std::cout << "p1 addres " << p1 << std::endl;


	std::cout << std::endl;

}


int main()
{

	singleton();

	simple_factory();

	factory_methods();

	abstract_factory();

	builderPatterns();

	builderPatterns2();

	prototypePatterns();

	return 0;
}

